using System;
using System.Resources;
using System.Threading;

namespace cmdSharePointExtractor
{
    /// <summary>
    /// This is the helper class for parsing the parameters.
    /// </summary>
    public class Parameters
    {
        /// <summary>
        /// This is a date threshold
        /// </summary>
        private DateTime exportItemsOlderThan = DateTime.MinValue;

        /// <summary>
        /// This is a date threshold
        /// </summary>
        private DateTime exportItemsNewerThan;

        /// <summary>
        /// This is a boolean flag controlling if .aspx pages are exported
        /// </summary>
        private bool exportDesign = false;

        /// <summary>
        /// This is a boolean flag controlling if versions are exported
        /// </summary>
        private bool exportVersions = true;

        /// <summary>
        /// This is the site collection owner login name
        /// </summary>
        private string owner = Thread.CurrentPrincipal.Identity.Name;

        /// <summary>
        /// This is the email address of the site collection owner
        /// </summary>
        private string contact = String.Empty;
        
        /// <summary>
        /// This is a boolean flag controlling if content from sub sites will be exported
        /// </summary>
        private bool includeSubWebs = true;

        /// <summary>
        /// This is the name of the directory that will contain the exported data
        /// </summary>
        private string outputDirectory;

        /// <summary>
        /// This is the URL to the site to be exported
        /// </summary>
        private string siteURL;

        /// <summary>
        /// This is a boolean flag controlling if list item IDs will be exported
        /// </summary>
        private bool exportIDs;

        /// <summary>
        /// This is a boolean flag controlling if user information will be exported
        /// </summary>
        private bool exportUserInfo = true;

        /// <summary>
        /// If set only this list will be exported
        /// </summary>
        private string list;

        /// <summary>
        /// If set only this folder will be exported
        /// </summary>
        private string folder = String.Empty;

        /// <summary>
        /// This is the name of the new site
        /// </summary>
        private string newName;

        /// <summary>
        /// This is the managed path used
        /// </summary>
        private string root;

        /// <summary>
        /// Boolean flag indicating whether or not the data should be compressed
        /// </summary>
        private bool compress;

        /// <summary>
        /// This is an internal resource manager
        /// </summary>
        private ResourceManager rm = null;

        /// <summary>
        /// Initializes a new instance of the Parameters class that is used for parsing the parameters
        /// </summary>
        public Parameters()
        {
            rm = ResourceManager.CreateFileBasedResourceManager("strings", ".", null);
        }

        /// <summary>
        /// Gets or sets the URL to the SharePoint site to be exported
        /// </summary>
        public string SiteURL
        {
            get
            {
                return this.siteURL;
            }

            set
            {
                this.siteURL = value;
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether subwebs should be processed
        /// </summary>
        public bool IncludeSubWebs
        {
            get
            {
                return this.includeSubWebs;
            }

            set
            {
                this.includeSubWebs = value;
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether design elements should be processed
        /// </summary>
        public bool ExtractDesign
        {
            get
            {
                return this.exportDesign;
            }

            set
            {
                this.exportDesign = value;
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether versions should be processed
        /// </summary>
        public bool ExportVersions
        {
            get
            {
                return this.exportVersions;
            }

            set
            {
                this.exportVersions = value;
            }
        }

        /// <summary>
        /// Gets or sets the new name of the site
        /// </summary>
        public string NewName
        {
            get
            {
                return this.newName;
            }

            set
            {
                this.newName = value;
            }
        }

        /// <summary>
        /// Gets or sets the managed path
        /// </summary>
        public string Root
        {
            get
            {
                return this.root;
            }

            set
            {
                int pos = value.IndexOf("/");

                if (pos == -1)
                {
                    this.root = value;
                }
                else
                {
                    string message = this.rm.GetString("RootArgEx");
                    ArgumentException argEx = new ArgumentException(message, "Root");
                    throw argEx;
                }
            }
        }

        /// <summary>
        /// Gets or sets the output directory
        /// </summary>
        public string OutputDirectory
        {
            get
            {
                return this.outputDirectory;
            }

            set
            {
                this.outputDirectory = value;
            }
        }

        /// <summary>
        /// Gets or sets the optional list parameter
        /// </summary>
        public string List
        {
            get
            {
                return this.list;
            }

            set
            {
                this.list = value;
            }
        }

        /// <summary>
        /// Gets or sets the site collection owner
        /// </summary>
        public string Owner
        {
            get
            {
                return this.owner;
            }

            set
            {
                this.owner = value;
            }
        }

        /// <summary>
        /// Gets the site collection owner's email
        /// </summary>
        public string Contact
        {
            get
            {
                return this.contact;
            }
        }

        /// <summary>
        /// Gets or sets the optional Folder that will be extracted
        /// </summary>
        public string Folder
        {
            get
            {
                return this.folder;
            }
            
            set
            {
                this.folder = value;
            }
        }

        /// <summary>
        /// Gets or sets the time threshold. If set only items newer than the threshold will be exported
        /// </summary>
        public DateTime ExportItemsNewerThan
        {
            get
            {
                return this.exportItemsNewerThan;
            }
            
            set
            {
                this.exportItemsNewerThan = value;
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether user data will be extracted
        /// </summary>
        public bool ExportUserInfo
        {
            get
            {
                return this.exportUserInfo;
            }

            set
            {
                this.exportUserInfo = value;
            }
        }

        /// <summary>
        /// Gets or sets the time threshold. If set only items older than the threshold will be exported
        /// </summary>
        public DateTime ExportItemsOlderThan
        {
            get
            {
                return this.exportItemsOlderThan;
            }

            set
            {
                this.exportItemsOlderThan = value;
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether or not the data should be compressed
        /// </summary>
        public bool Compress
        {
            get
            {
                return this.compress;
            }
            set
            {
                this.compress = value;
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether the List IDs are exported
        /// </summary>
        public bool ExportIDs
        {
            get
            {
                return this.exportIDs;
            }

            set
            {
                this.exportIDs = value;
            }
        }

        /// <summary>
        /// This method processes the commandline arguments
        /// </summary>
        /// <param name="args">Command line arguments</param>
        /// <returns>true if succeeded</returns>
        public bool ReadParameters(string[] args)
        {
            bool returnValue = true;
            for (int i = 0; i < args.GetLength(0); i += 2)
            {
                string lowerarg = args[i].ToLower();
                string data = args[i + 1];
                switch (lowerarg)
                {
                    case "-compress":
                        this.Compress = bool.Parse(args[i + 1]);
                        break;
                    case "-contact":
                        this.contact = args[i + 1];
                        break;
                    case "-exportuserinfo":
                        this.ExportUserInfo = bool.Parse(args[i + 1]);
                        break;
                    case "-exportdesign":
                        this.exportDesign = bool.Parse(args[i + 1]);
                        break;
                    case "-exportversioninfo":
                        this.ExportVersions = bool.Parse(args[i + 1]);
                        break;
                    case "-extractids":
                        this.ExportIDs = bool.Parse(args[i + 1]);
                        break;
                    case "-exportitemsnewerthan":
                        this.ExportItemsNewerThan = DateTime.Parse(args[i + 1]);
                        break;
                    case "-exportitemsolderthan":
                        this.ExportItemsOlderThan = DateTime.Parse(args[i + 1]);
                        break;
                    case "-folder":
                        this.Folder = args[i + 1];
                        break;
                    case "-includesubwebs":
                        this.IncludeSubWebs = bool.Parse(args[i + 1]);
                        break;
                    case "-list":
                        this.List = args[i + 1];
                        break;
                    case "-newname":
                        this.NewName = args[i + 1];
                        break;
                    case "-out":
                    case "-outputdirectory":
                        this.OutputDirectory = args[i + 1];
                        break;
                    case "-owner":
                        this.owner = args[i + 1];
                        break;
                    case "-root":
                        this.Root = args[i + 1];
                        break;
                    case "-url":
                        this.SiteURL = args[i + 1];
                        break;
                }
            }

            if (String.IsNullOrEmpty(this.SiteURL) || String.IsNullOrEmpty(NewName) || String.IsNullOrEmpty(this.OutputDirectory))
            {
                returnValue = false;
            }
            else
            {
                returnValue = true;
            }

            return returnValue;
        }
    }
}
